package dk.dashboardFP.uiElements.scrollbar {
	import dk.dashboardFP.utils.Range;

	import flash.display.InteractiveObject;
	import flash.events.EventDispatcher;
	import flash.events.MouseEvent;

	/**
	 * @author jk
	 */
	public class GenericScrollLink extends EventDispatcher implements IScrollLink {

		private var _nScrollArea : Number;
		private var _nWindowArea : Number;
		private var _rangeScrollRange : Range;
		private var _oScrollbar : Scrollbar;
		private var _nScrollPosRate : Number = 0;
		private var _nMouseWheelMultiplyer : Number = 1;
		private var _bIsActive : Boolean=true;
		private var _nStepSize : Number=10;

		public function GenericScrollLink(nScrollArea : Number, nWindowArea : Number, oInteractivityObject : InteractiveObject=null) {
			
			_nWindowArea = nWindowArea;
			_nScrollArea = nScrollArea;
			
			if (oInteractivityObject!=null) {
				oInteractivityObject.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel, false, 0, true);
			}
			
			updateRange();
		}
		
		private function onMouseWheel(event : MouseEvent) : void {
			event.stopImmediatePropagation();
			nScrollPos -= event.delta*_nMouseWheelMultiplyer;
		}

		private function updateRange() : void {
			_rangeScrollRange=new Range(0, (_nScrollArea - _nWindowArea));
			
		}
		
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// inactive active
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		
		public function setInactive() : void {
			_nScrollPosRate=0;
			dispatchEvent(new ScrollLinkEvent(ScrollLinkEvent.SCROLL_CHANGE));
			_bIsActive=false;
			dispatchEvent(new ScrollLinkEvent(ScrollLinkEvent.SET_INACTIVE));
		}

		public function setActive() : void {
			_bIsActive=true;
			dispatchEvent(new ScrollLinkEvent(ScrollLinkEvent.SET_ACTIVE));
		}

		//
		
		public function set nScrollPos(oNewValue : Number) : void {
			
			if (!_bIsActive) {
				return;
			}
			
			_nScrollPosRate = _rangeScrollRange.getRate(oNewValue);
			dispatchEvent(new ScrollLinkEvent(ScrollLinkEvent.SCROLL_CHANGE));
			
			// removed
			//dispatchEvent(new GenericScrollLinkEvent(GenericScrollLinkEvent.SCROLL_CHANGED));
		}
		
		public function get nScrollPos() : Number { 
			return Math.round(_rangeScrollRange.getPosition(_nScrollPosRate));
		}
		
		public function registerScrollbar(oScrollbar : Scrollbar) : void {
			_oScrollbar = oScrollbar;
			
			_oScrollbar.addEventListener(ScrollBarEvent.SCROLL_RATE_CHANGED, onScrollRateChangeOnBar, false, 0, true);
			
			_oScrollbar.addEventListener(ScrollBarEvent.STEP_UP, onStepUp, false, 0, true);
			_oScrollbar.addEventListener(ScrollBarEvent.STEP_DOWN, onStepDown, false, 0, true);
			
			_oScrollbar.addEventListener(ScrollBarEvent.PAGE_UP, onPageUp, false, 0, true);
			_oScrollbar.addEventListener(ScrollBarEvent.PAGE_DOWN, onPageDown, false, 0, true);
			
		}
		
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// page up / Down
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		
		protected function onPageDown(event : ScrollBarEvent) : void {
			nScrollPos += _nWindowArea;
		}

		protected function onPageUp(event : ScrollBarEvent) : void {
			nScrollPos -= _nWindowArea;
		}

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// step up down
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		
		private function onStepUp(event : ScrollBarEvent) : void {
			nScrollPos -= _nStepSize;
		}	
			
		private function onStepDown(event : ScrollBarEvent) : void {
			nScrollPos += _nStepSize;
		}
		
		//:::::::
		// 

		private function onScrollRateChangeOnBar(event : ScrollBarEvent) : void {
			_nScrollPosRate = _oScrollbar.nScrollRage;
			dispatchEvent(new ScrollLinkEvent(ScrollLinkEvent.SCROLL_CHANGE));
		}
				
		public function get nScrollPosRate() : Number {
			return _nScrollPosRate;
		}
		
		public function set nScrollPosRate(oNewValue : Number) : void { 
			 _nScrollPosRate=oNewValue;
			dispatchEvent(new ScrollLinkEvent(ScrollLinkEvent.SCROLL_CHANGE));  
		}
		
		private function dispatchLinkSettingsChanged() : void {
			dispatchEvent(new ScrollLinkEvent(ScrollLinkEvent.SCROLL_LINK_SETTINGS_CHANGED));
			
		}
		
		// space factor
		public function get nScrollSpaceFactor() : Number {
			var nReturn : Number=_nWindowArea / _nScrollArea;
			
			if (nReturn>1) {
				nReturn=1;
			}
			if (nReturn<=0) {
				nReturn=0.01;
			}
			return nReturn; 
		}
		
		public function get nMouseWheelMultiplyer() : Number {
			return _nMouseWheelMultiplyer;
		}
		
		public function set nMouseWheelMultiplyer(nMouseWheelMultiplyer : Number) : void {
			_nMouseWheelMultiplyer = nMouseWheelMultiplyer;
		}
		
		public function get nScrollArea() : Number {
			return _nScrollArea;
		}
		
		public function set nScrollArea(nScrollArea : Number) : void {
			_nScrollArea = nScrollArea;
			
			var nTemp : Number = _rangeScrollRange.getPosition(_nScrollPosRate);
			updateRange();
			
			_nScrollPosRate = _rangeScrollRange.getRate(nTemp);
			
			dispatchLinkSettingsChanged();
			dispatchEvent(new ScrollLinkEvent(ScrollLinkEvent.SCROLL_CHANGE));
		}
		
		public function get nWindowArea() : Number {
			return _nWindowArea;
		}
		
		public function set nWindowArea(nWindowArea : Number) : void {
			_nWindowArea = nWindowArea;
			
			updateRange();
			
			dispatchLinkSettingsChanged();
			dispatchEvent(new ScrollLinkEvent(ScrollLinkEvent.SCROLL_CHANGE));
		}
		
		public function get bIsActive() : Boolean {
			return _bIsActive;
		}
		
		public function get nStepSize() : Number {
			return _nStepSize;
		}
		
		public function set nStepSize(nStepSize : Number) : void {
			_nStepSize = nStepSize;
		}
	}
}
